package main

import (
	"flag"
	//"flag"
	"os"
	//"strings"
	"fmt"
	"image/color"
	"image/jpeg"
	"sync"
	"time"

	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/app"
	"fyne.io/fyne/v2/canvas"
	"fyne.io/fyne/v2/container"
	"fyne.io/fyne/v2/data/binding"
	"fyne.io/fyne/v2/widget"
)

var scale float32 = 1.0
var rawW, rawH float32
var scaleAble = &sync.Mutex{}

var fname binding.String

func main() {
	flag.Parse()
	fname = binding.NewString()

	myApp := app.New()
	myWindow := myApp.NewWindow("ImageViewer")

	img := canvas.NewRectangle(color.White)

	scroll := container.NewScroll(img)

	pathname := widget.NewEntryWithData(fname)
	pathname.OnChanged = func(p string) {
		if len(p) == 0 {
			return
		}
		err := setJpeg(p, scroll)
		if err != nil {
			return
		}
		myWindow.Content().Refresh()
		myWindow.Show()
	}

	content := container.NewBorder(nil, nil, nil, nil, scroll)

	myWindow.SetContent(content)
	//myWindow.SetFixedSize(true)
	myWindow.Resize(fyne.NewSize(800, 600))
	myWindow.Canvas().SetOnTypedKey(func(e *fyne.KeyEvent) {
		switch e.Name {
		case "+":
			scaleAble.Lock()
			if scale < 1.0 {
				scale = scale + 0.1
			}
			scaleAble.Unlock()
		case "=":
			scaleAble.Lock()
			if scale < 1.0 {
				scale = scale + 0.1
			}
			scaleAble.Unlock()
		case "-":
			scaleAble.Lock()
			if scale > 0.2 {
				scale = scale - 0.1
			}
			scaleAble.Unlock()
		case "_":
			scaleAble.Lock()
			if scale > 0.2 {
				scale = scale - 0.1
			}
			scaleAble.Unlock()
		case "Right":
			if len(names) == 0 {
				return
			}
			imgIdx = (imgIdx + 1) % len(names)
			fname.Set(names[imgIdx])
			return
		case "Left":
			if len(names) == 0 {
				return
			}
			if imgIdx == 0 {
				imgIdx = len(names) - 1
			} else {
				imgIdx -= 1
			}
			fname.Set(names[imgIdx])
			return
		}

		//scroll.Content.(*canvas.Image).SetMinSize(fyne.NewSize(rawW*scale, rawH*scale))
		sz := fyne.NewSize(rawW*scale, rawH*scale)
		scroll.Content.(*canvas.Image).SetMinSize(sz)
		scroll.Content.(*canvas.Image).Resize(sz)

		scroll.Refresh()
	})
	if flag.Arg(0) == "" {
		fname.Set("blank")
	} else {
		fname.Set(flag.Arg(0))
	}
	go pathWaiter()
	//go jpegLoop()
	go func() {
		time.Sleep(time.Second * 3)
		setWindowTopMost("ImageViewer")
	}()
	myWindow.ShowAndRun()
}

func jpegLoop() {
	var names = []string{"t1.jpg", "t2.jpg"}
	var i int
	for {
		time.Sleep(time.Second * 3)
		fname.Set(names[i%2])
		fmt.Println(names[i%2])
		i++
	}
}

func setJpeg(name string, p *container.Scroll) error {
	imgSize, err := getJpegSize(name)
	if err != nil {
		return err
	}
	img := canvas.NewImageFromFile(name)
	if img == nil {
		return fmt.Errorf("Can not load image file.")
	}
	img.SetMinSize(*imgSize)

	p.Content = img

	p.Refresh()
	return nil
}

func getJpegSize(path string) (*fyne.Size, error) {
	fp, err := os.Open(path)
	if err != nil {
		return nil, err
	}
	defer fp.Close()
	img, err := jpeg.Decode(fp)
	if err != nil {
		return nil, err
	}
	rect := img.Bounds()
	w := rect.Max.X
	h := rect.Max.Y
	rawW = float32(w)
	rawH = float32(h)
	scaleAble.Lock()
	res := fyne.NewSize(float32(w)*scale, float32(h)*scale)
	scaleAble.Unlock()
	return &res, nil
}
